#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import time
import logging
import requests
import json

logging.getLogger().setLevel(logging.DEBUG)
logging.debug("debug mode enabled")

API_LIST_FILE = os.getenv('API_LIST_FILE') or 'api_list'
OPENTSDB_HTTP_API = os.getenv('OPENTSDB_HTTP_API') or '106.120.241.178:4242'
SAMPLE_INTERVAL = int(os.getenv('SAMPLE_INTERVAL') or 30)


def _load_api_list():
    with open(API_LIST_FILE) as f:
        content = f.readlines()
        content = [x.strip().split() for x in content if not x.strip().startswith('#')]
    return content


class Metrics:
    def __init__(self, api_health_metric='goldwind.kmx.api.health', api_downtime_metric='goldwind.kmx.api.downtime'):
        self._api_health_metric = api_health_metric
        self._api_downtime_metric = api_downtime_metric
        self._now = int(time.time())
        self._global_health = True
        self.json = []
        pass

    def _make_api_health_metric(self, ts, value, **tags):
        return {
            'metric': self._api_health_metric,
            'timestamp': int(ts),
            'value': value,
            'tags': tags
        }

    def _make_api_downtime_metric(self, ts, value, **tags):
        return {
            'metric': self._api_downtime_metric,
            'timestamp': int(ts),
            'value': value,
            'tags': tags
        }

    def record_success(self, name=str):
        self.json.append(self._make_api_health_metric(self._now, 1, name=name))

    def record_failure(self, name=str, downtime=int):
        self.json.append(self._make_api_health_metric(self._now, 0, name=name))
        self.json.append(self._make_api_downtime_metric(self._now, downtime, name=name))
        self._global_health = False

    def record_global_health(self, sample_interval):
        if self._global_health:
            self.record_success('all')
        else:
            self.record_failure('all', sample_interval)

    def __str__(self):
        return json.dumps(self.json)


def _send_metrics(metrics, session=None):
    url = "http://%s/api/put" % OPENTSDB_HTTP_API
    try:
        if session is None:
            response = requests.post(url, data=json.dumps(metrics.json))
        else:
            print session.__dict__
            response = session.post(url, data=json.dumps(metrics.json))
        if response.status_code == 204:
            logging.info("metrics send to %s success" % OPENTSDB_HTTP_API)
    except requests.exceptions.RequestException as e:
        logging.error(e.message)


if __name__ == '__main__':
    s = requests.Session()
    while True:
        now = time.time()
        api_list = _load_api_list()
        logging.debug(api_list)
        # send metrics in a batch
        metrics = Metrics()
        # check api for each one
        for api in api_list:
            try:
                response = requests.get(api[1])
                if response.status_code == 200:
                    metrics.record_success(api[0])
                else:
                    metrics.record_failure(api[0], SAMPLE_INTERVAL)
            except requests.exceptions.RequestException as e:
                logging.error(e.message)
                metrics.record_failure(api[0], SAMPLE_INTERVAL)
        # global api health status
        metrics.record_global_health(SAMPLE_INTERVAL)
        print metrics
        _send_metrics(metrics, s)
        time.sleep(SAMPLE_INTERVAL)

